package zt.song.filter;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import zt.song.common.Const;
import zt.song.exception.CaptchaException;
import zt.song.security.LoginFailureHandler;
import zt.song.util.JwtUtils;
import zt.song.util.RedisUtil;

import java.io.IOException;
import java.util.TreeSet;

/**
 * @Author 宋伟宁
 * @Date 2023/11/21
 * @Version 1.0
 **/
@Slf4j
@Component
@Order(-102)
public class CaptchaFilter extends OncePerRequestFilter {
    private final String loginUrl = "/login";
    @Resource
    RedisUtil redisUtil;
    @Resource
    JwtUtils jwtUtils;
    @Resource
    LoginFailureHandler loginFailureHandler;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String url = request.getRequestURI();
        if (loginUrl.equals(url) && request.getMethod().equals("POST")) {
            log.info("获取到login链接，正在校验验证码 -- " + url);
            try {
                validate(request);
            } catch (CaptchaException e) {
                log.info(e.getMessage());
                // 交给登录失败处理器处理
                loginFailureHandler.onAuthenticationFailure(request, response, e);
            }
        }else{
            log.info("jwt 校验 filter");
            String jwt = request.getHeader(jwtUtils.getHeader());
            if (StrUtil.isBlankOrUndefined(jwt)) {
                filterChain.doFilter(request, response);
                return;
            }
            Claims claim = jwtUtils.getClaimByToken(jwt);
            if (claim == null) {
                throw new JwtException("token异常！");
            }
            if (jwtUtils.isTokenExpired(claim)) {
                throw new JwtException("token已过期");
            }
            //
            String username = claim.getSubject();
            log.info("用户-{}，正在登陆！", username);
            //获取账号的权限：role
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
                    = new UsernamePasswordAuthenticationToken(username, null, new TreeSet<>());
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
           // filterChain.doFilter(request, response);
        }
        filterChain.doFilter(request, response);
    }
    private void validate(HttpServletRequest request) {
        String code = request.getParameter("code");
        String token = request.getParameter("token");
        if (StringUtils.isBlank(code) || StringUtils.isBlank(token)) {
            throw new CaptchaException("验证码不能为空");
        }
        String str =(String) redisUtil.hget(Const.captcha_KEY, token);
//        Object str = redisUtil.hget(Const.captcha_KEY, code);
        System.err.println("redis中的验证码是："+str);
        if(!code.equals(str)) {
            throw new CaptchaException("验证码不正确");
        }
        // 一次性使用
        redisUtil.hdel(Const.captcha_KEY, token);
    }
}
